#include <iostream>

template <typename... Ts>
struct TypeList {};

template <typename T>
struct Length;

template <typename T, typename... Ts>
struct Length<TypeList<T, Ts...>> {
    static constexpr int value = 1 + Length<TypeList<Ts...>>::value;
};

template <>
struct Length<TypeList<>> {
    static constexpr int value = 0;
};

template <typename T, typename List, int Index = 0>
struct Find;

template <typename T, typename... Ts, int Index>
struct Find<T, TypeList<T, Ts...>, Index> {
    static constexpr int value = Index;
};

template <typename T, typename U, typename... Ts, int Index>
struct Find<T, TypeList<U, Ts...>, Index> {
    static constexpr int value = Find<T, TypeList<Ts...>, Index + 1>::value;
};

template <typename T, int Index>
struct Find<T, TypeList<>, Index> {
    static constexpr int value = -1;
};

int main() {
    using MyTypes = TypeList<int, float, double, char>;

    constexpr int len = Length<MyTypes>::value;
    constexpr int index1 = Find<int, MyTypes>::value;
    constexpr int index2 = Find<float, MyTypes>::value;
    constexpr int index3 = Find<double, MyTypes>::value;
    constexpr int index4 = Find<char, MyTypes>::value;
    constexpr int index5 = Find<long, MyTypes>::value;

    std::cout << "Length<MyTypes>::value: " << len << std::endl;  // 输出 4
    std::cout << "Find<int, MyTypes>::value: " << index1
              << std::endl;  // 输出 0
    std::cout << "Find<float, MyTypes>::value: " << index2
              << std::endl;  // 输出 1
    std::cout << "Find<double, MyTypes>::value: " << index3
              << std::endl;  // 输出 2
    std::cout << "Find<char, MyTypes>::value: " << index4
              << std::endl;  // 输出 3
    std::cout << "Find<long, MyTypes>::value: " << index5
              << std::endl;  // 输出 -1

    return 0;
}